package com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.PictureType;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.policy.PictureRenderPolicy;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ExceptionCast;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.ApiModelUtil;
import com.xyht.sca_s.student_manage_system.common.util.CacheUtil;
import com.xyht.sca_s.student_manage_system.common.util.TimeUtil;
import com.xyht.sca_s.student_manage_system.common.util.XWPFTUtil;
import com.xyht.sca_s.student_manage_system.modules.agreement.entity.SmsAgreementApplication;
import com.xyht.sca_s.student_manage_system.modules.common.constant.FileSavePathConstant;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.AppTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.RangeTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.TipsTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.util.NewTipsUtil;
import com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.entity.SmsUseMoneyApplication;
import com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.entity.SmsUseMoneyApplicationDetail;
import com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.entity.SmsUseMoneyApplicationProcess;
import com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.entity.dto.*;
import com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.entity.vo.*;
import com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.mapper.SmsUseMoneyApplicationDetailMapper;
import com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.mapper.SmsUseMoneyApplicationMapper;
import com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.mapper.SmsUseMoneyApplicationMpjMapper;
import com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.mapper.SmsUseMoneyApplicationProcessMapper;
import com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.service.SmsUseMoneyApplicationService;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsRole;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsRoleMapper;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsUserMapper;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.examinePaymentEquipment.constant.isExportProcessConstant.EXPORT_PROCESS_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.examinePaymentEquipment.constant.paymentExamineStatusConstant.EXAMINE_STATUS_DENY;
import static com.xyht.sca_s.student_manage_system.modules.examinePaymentEquipment.constant.paymentExamineStatusConstant.EXAMINE_STATUS_PASS;
import static com.xyht.sca_s.student_manage_system.modules.student.constant.StudentInfoCommonConstant.PER_SHEET_NUM;
import static com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.constant.ApplicationState.*;
import static com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.constant.useMoneyApplicationStatusConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.constant.useMoneyApplicationTypeConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.constant.useMoneyObjectTypeConstant.USE_MONEY_APPLICATION_OBJECT_TYPE_PERSON;
import static com.xyht.sca_s.student_manage_system.modules.useMoneyApplication.constant.useMoneyObjectTypeConstant.USE_MONEY_APPLICATION_OBJECT_TYPE_ROLE;
import static com.xyht.sca_s.student_manage_system.modules.visitor.contact.CheckType.PROCESS_PEOPLE_CHECK_TYPE;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2023-05-14
 */
@Service
public class SmsUseMoneyApplicationServiceImpl extends ServiceImpl<SmsUseMoneyApplicationMapper, SmsUseMoneyApplication> implements SmsUseMoneyApplicationService {
    @Autowired
    SmsUseMoneyApplicationProcessMapper smsUseMoneyApplicationProcessMapper;
    @Autowired
    SmsUseMoneyApplicationMapper smsUseMoneyApplicationMapper;
    @Autowired
    SmsUseMoneyApplicationDetailMapper smsUseMoneyApplicationDetailMapper;
    @Autowired
    NewTipsUtil newTipsUtil;
    @Autowired
    CacheUtil cacheUtil;
    @Autowired
    SmsUseMoneyApplicationMpjMapper smsUseMoneyApplicationMpjMapper;
    @Autowired
    ApiModelUtil apiModelUtil;
    @Autowired
    SmsUserMapper smsUserMapper;
    @Autowired
    SmsRoleMapper smsRoleMapper;
    @Resource
    private FileSavePathConstant fileSavePathConstant;

    @Transactional
    @Override
    public ResponseResult smsUseMoneyApplicationAdd(SmsUseMoneyApplicationVO smsUseMoneyApplicationVO,String user_id) {
        List<SmsUseMoneyApplicationProcess> fillProcessList =
                smsUseMoneyApplicationProcessMapper.selectList(new QueryWrapper<SmsUseMoneyApplicationProcess>()
                        .lambda()
                        .eq(SmsUseMoneyApplicationProcess::getProcessIsApplicationEdit, true)
                        .eq(SmsUseMoneyApplicationProcess::getIsUse, true)
                        .orderByAsc(SmsUseMoneyApplicationProcess::getSort));
        if (fillProcessList != null && fillProcessList.size() > 0) {
            if (smsUseMoneyApplicationVO.getProcessList() == null || smsUseMoneyApplicationVO.getProcessList().size() < 1) {
                return CommonResult.failed(CommonCodeEnum.USE_MONEY_ALLOW_USER_NOT_SETTING);
            }
            //判断申请人是否将全部需要编辑流程填写
            List<SmsUseMoneyApplicationProcess> filterList = fillProcessList
                    .stream()
                    .filter(process -> {
                                List<String> result = smsUseMoneyApplicationVO.getProcessList()
                                        .stream()
                                        .filter(fillProcess -> fillProcess.getProcessId().equals(process.getId()))
                                        .map(SmsUseMoneyApplicationDetailVO::getId)
                                        .collect(Collectors.toList());
                                //匹配的去除  未匹配的留下
                                if (result.size() > 0) {
                                    return false;
                                } else {
                                    return true;
                                }
                            }
                    )
                    .collect(Collectors.toList());
            if (filterList.size() > 0) {
                return CommonResult.failed(CommonCodeEnum.USE_MONEY_ALLOW_PROCESS_NOT_FILL);
            }
        }

        SmsUseMoneyApplication smsUseMoneyApplication = new SmsUseMoneyApplication();
        BeanUtils.copyProperties(smsUseMoneyApplicationVO, smsUseMoneyApplication);

        smsUseMoneyApplication.setUserId(user_id);
        smsUseMoneyApplication.setSmsApplicationState(USE_MONEY_REGISTER_PROCESS_WAITING);
        smsUseMoneyApplicationMapper.insert(smsUseMoneyApplication);

        if (smsUseMoneyApplication.getId() == null) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.FAIL));
        }
        String application_id = smsUseMoneyApplication.getId();

        //创建审批流程
        List<SmsUseMoneyApplicationProcess> originProcessList =
                smsUseMoneyApplicationProcessMapper.selectList(new QueryWrapper<SmsUseMoneyApplicationProcess>()
                        .lambda()
                        .eq(SmsUseMoneyApplicationProcess::getIsUse, 1)
                        .orderByAsc(SmsUseMoneyApplicationProcess::getSort));
        if (originProcessList == null || originProcessList.size() < 1) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.USE_MONEY_PROCESS_NOT_SETTING));
        }
        int sort = 1;
        for (SmsUseMoneyApplicationProcess process : originProcessList) {
            if(!process.getProcessIsApplicationEdit()&&isNullOrEmpty(process.getCheckId())){
                ExceptionCast.cast( CommonResult.failed(CommonCodeEnum.USE_MONEY_PROCESS_NOT_SETTING));
            }


            SmsUseMoneyApplicationDetail addDetail =
                    new SmsUseMoneyApplicationDetail();

            addDetail.setApplicationId(application_id);
            addDetail.setProcessId(process.getId());
            addDetail.setProcessIsSign(process.getProcessIsSign());
            addDetail.setProcessIsStamp(process.getProcessIsStamp());
            addDetail.setProcessName(process.getProcessName());
            addDetail.setDetailAllowStatus(USE_MONEY_APPLICATION_STATUS_WAIT_ALLOW);
            addDetail.setApplicationState(USE_MONEY_REGISTER_PROCESS_WAITING);
            addDetail.setSort(sort++);

            //申请人可编辑流程
            if (process.getProcessIsApplicationEdit()) {
                List<SmsUseMoneyApplicationDetailVO> filterList = smsUseMoneyApplicationVO.getProcessList()
                        .stream()
                        .filter(fillProcess -> fillProcess.getProcessId().equals(process.getId()))
                        .collect(Collectors.toList());
                if (filterList.size() < 1) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.USE_MONEY_ALLOW_PROCESS_NOT_FILL));
                }
                SmsUseMoneyApplicationDetailVO fillProcessReq = filterList.get(0);

                if (isNullOrEmpty(fillProcessReq.getCheckId())) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
                }
                addDetail.setCheckId(fillProcessReq.getCheckId());
                addDetail.setCheckType(USE_MONEY_APPLICATION_OBJECT_TYPE_PERSON);
            } else {
                addDetail.setCheckId(process.getCheckId());
                addDetail.setCheckType(process.getCheckType());
            }
            smsUseMoneyApplicationDetailMapper.insert(addDetail);
        }

        //消息通知
        //通知流程第一个节点
        //消息通知
        QueryWrapper<SmsUseMoneyApplicationDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SmsUseMoneyApplicationDetail::getApplicationId, smsUseMoneyApplication.getId())
                .eq(SmsUseMoneyApplicationDetail::getSort, 1)
                .orderByAsc(SmsUseMoneyApplicationDetail::getSort);
        SmsUseMoneyApplicationDetail applicationDetail
                = smsUseMoneyApplicationDetailMapper.selectOne(queryWrapper);
        RangeTypeEnum rangeTypeEnum;
        if(applicationDetail.getProcessIsApplicationEdit().equals(1)){
            rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_PERSON;
        }
        else{
            if (applicationDetail.getCheckType() == USE_MONEY_APPLICATION_OBJECT_TYPE_PERSON) {
                rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_ROLE;
            } else {
                rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_PERSON;
            }
        }

        List<String> range_id_list = new ArrayList<>();
        range_id_list.add(applicationDetail.getCheckId());
        newTipsUtil.addNewTips(TipsTypeEnum.TIPS_TYPE_ENUM_ALLOW,
                user_id,
                rangeTypeEnum,
                range_id_list,
                AppTypeEnum.APP_TYPE_ENUM_USE_MONEY_APPLICATION,
                smsUseMoneyApplication.getId(),
                applicationDetail.getId()
        );
        return CommonResult.success();
    }

    @Override
    public ResponseResult smsUseMoneyApplicationCancel(SmsUseMoneyCancelVO smsUseMoneyCancelVO, String user_id) {
        if(isNullOrEmpty(smsUseMoneyCancelVO.getApplication_id())){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        //查看审批表是否存在且是否为本人
        SmsUseMoneyApplication application =
                smsUseMoneyApplicationMapper.selectOne(new QueryWrapper<SmsUseMoneyApplication>()
                        .lambda()
                        .eq(SmsUseMoneyApplication::getId, smsUseMoneyCancelVO.getApplication_id())
                        .eq(SmsUseMoneyApplication::getUserId, user_id));
        if (application == null || isNullOrEmpty(application.getId())) {
            return CommonResult.failed(CommonCodeEnum.USE_MONEY_NOT_EXIST);
        }
        if (application.getSmsApplicationState() != USE_MONEY_REGISTER_PROCESS_WAITING) {
            return CommonResult.failed(CommonCodeEnum.USE_MONEY_CANCEL_FAIL_ALLOWED);
        }
        //判断是否审批中
//        List<SmsUseMoneyApplicationDetail> detailList =
//                smsUseMoneyApplicationDetailMapper.selectList(new QueryWrapper<SmsUseMoneyApplicationDetail>()
//                        .lambda()
//                        .eq(SmsUseMoneyApplicationDetail::getApplicationId, smsUseMoneyCancelVO.getApplication_id())
//                        .eq(SmsUseMoneyApplicationDetail::getDetailAllowStatus, USE_MONEY_APPLICATION_STATUS_PASS));
//        if (detailList != null && detailList.size() > 0) {
//            return CommonResult.failed(CommonCodeEnum.USE_MONEY_CANCEL_FAIL_ALLOWING);
//        }
        //撤回审批
        SmsUseMoneyApplication cancelApplication = new SmsUseMoneyApplication();
        cancelApplication.setId(smsUseMoneyCancelVO.getApplication_id());
        cancelApplication.setSmsApplicationState(USE_MONEY_APPLICATION_STATUS_CANCEL);
        cancelApplication.setSmsProcessEndTime(new Date());
        smsUseMoneyApplicationMapper.updateById(cancelApplication);

        //修改节点状态
        SmsUseMoneyApplicationDetail cancelApplicationDetail = new SmsUseMoneyApplicationDetail();
        cancelApplicationDetail.setDetailAllowStatus(USE_MONEY_APPLICATION_STATUS_CANCEL);
        smsUseMoneyApplicationDetailMapper.update(cancelApplicationDetail, new QueryWrapper<SmsUseMoneyApplicationDetail>()
                .lambda()
                .eq(SmsUseMoneyApplicationDetail::getApplicationId, smsUseMoneyCancelVO.getApplication_id())
                .eq(SmsUseMoneyApplicationDetail::getDetailAllowStatus,USE_MONEY_APPLICATION_STATUS_WAIT_ALLOW));

        //消息通知
        newTipsUtil.cancelFinishTips(smsUseMoneyCancelVO.getApplication_id());
        return CommonResult.success();
    }

    @Override
    public ResponseResult smsUseMoneyApplicationAllow(SmsUseMoneyApplicationAllowVO allowVO, String user_id) {
        if (isNullOrEmpty(allowVO.getApplicationId()) || isNullOrEmpty(allowVO.getDetailId())
                || isNullOrEmpty(allowVO.getAllowDetailStatus())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        //判断审批状态不是为通过状态
        if (allowVO.getAllowDetailStatus() != USE_MONEY_APPLICATION_STATUS_PASS
                && allowVO.getAllowDetailStatus() != USE_MONEY_APPLICATION_STATUS_DENY) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsUseMoneyApplicationDetail useMoneyApplicationDetail =
                smsUseMoneyApplicationDetailMapper.selectOne(new QueryWrapper<SmsUseMoneyApplicationDetail>()
                        .lambda()
                        .eq(SmsUseMoneyApplicationDetail::getApplicationId, allowVO.getApplicationId())
                        .eq(SmsUseMoneyApplicationDetail::getId, allowVO.getDetailId())
                        .eq(SmsUseMoneyApplicationDetail::getDetailAllowStatus, USE_MONEY_APPLICATION_STATUS_WAIT_ALLOW));
        if (useMoneyApplicationDetail == null || isNullOrEmpty(useMoneyApplicationDetail.getId())) {
            return CommonResult.failed(CommonCodeEnum.USE_MONEY_ALLOW_PROCESS_HAVE);
        }
        //判断该节点是否本人审批（防止调节点审批）
        if(useMoneyApplicationDetail.getCheckType() == USE_MONEY_APPLICATION_OBJECT_TYPE_PERSON){
            if(!useMoneyApplicationDetail.getCheckId().equals(user_id)){
                return CommonResult.failed(CommonCodeEnum.USE_MONEY_ALLOW_FAIL);
            }
        }else{
            List<String> roleList = cacheUtil.getRoleList(user_id);
            List<String> filterRoleList = roleList.stream().filter(role -> role.equals(useMoneyApplicationDetail.getCheckId())).collect(Collectors.toList());
            if(filterRoleList.size()<1){
                return CommonResult.failed(CommonCodeEnum.USE_MONEY_ALLOW_FAIL);
            }
        }
        if(!useMoneyApplicationDetail.getSort().equals(1)){
            SmsUseMoneyApplicationDetail preDetail =
                    smsUseMoneyApplicationDetailMapper.selectOne(new QueryWrapper<SmsUseMoneyApplicationDetail>()
                            .lambda()
                            .eq(SmsUseMoneyApplicationDetail::getApplicationId,allowVO.getApplicationId())
                            .eq(SmsUseMoneyApplicationDetail::getSort,useMoneyApplicationDetail.getSort()-1));
            if(preDetail!=null && !isNullOrEmpty(preDetail.getId())){
                if(preDetail.getDetailAllowStatus()!=USE_MONEY_APPLICATION_STATUS_PASS){
                    return CommonResult.failed(CommonCodeEnum.USE_MONEY_ALLOW_FAIL);
                }
            }
        }


        SmsUseMoneyApplicationDetail allowDetail = new SmsUseMoneyApplicationDetail();
        allowDetail.setId(allowVO.getDetailId());
        allowDetail.setDetailAllowStatus(allowVO.getAllowDetailStatus());
        if (!isNullOrEmpty(allowVO.getDetailAllowOpinion())) {
            allowDetail.setDetailAllowOption(allowVO.getDetailAllowOpinion());
        }
        Date nowDate = new Date();
        allowDetail.setProcessTime(nowDate);
        allowDetail.setAllowUserId(user_id);

        if (useMoneyApplicationDetail.getProcessIsSign()) {
            if (isNullOrEmpty(allowVO.getDetailAllowSign())) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
            allowDetail.setDetailAllowSign(allowVO.getDetailAllowSign());
        }
        if (useMoneyApplicationDetail.getProcessIsStamp()) {
            if (isNullOrEmpty(allowVO.getDetailAllowStamp())) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
            allowDetail.setDetailAllowStamp(allowVO.getDetailAllowStamp());
        }
        smsUseMoneyApplicationDetailMapper.updateById(allowDetail);

        boolean is_done = false;
        //判断是否最后一个节点 是否驳回
        Integer detailCount = smsUseMoneyApplicationDetailMapper.selectCount(new QueryWrapper<SmsUseMoneyApplicationDetail>()
                .lambda()
                .eq(SmsUseMoneyApplicationDetail::getApplicationId, allowVO.getApplicationId()));
        if (detailCount.equals(useMoneyApplicationDetail.getSort()) && allowVO.getAllowDetailStatus() == USE_MONEY_APPLICATION_STATUS_DENY) {
            is_done = true;
            SmsUseMoneyApplication updateApplication = new SmsUseMoneyApplication();
            updateApplication.setId(allowVO.getApplicationId());
            updateApplication.setSmsProcessEndTime(nowDate);
            updateApplication.setSmsApplicationState(USE_MONEY_REGISTER_PROCESS_LOSS);
            smsUseMoneyApplicationMapper.updateById(updateApplication);
        }
        else if(detailCount.equals(useMoneyApplicationDetail.getSort()) && allowVO.getAllowDetailStatus() == USE_MONEY_APPLICATION_STATUS_PASS){
            is_done = true;
            SmsUseMoneyApplication updateApplication = new SmsUseMoneyApplication();
            updateApplication.setId(allowVO.getApplicationId());
            updateApplication.setSmsProcessEndTime(nowDate);
            updateApplication.setSmsApplicationState(USE_MONEY_REGISTER_PROCESS_SUCCESS);
            smsUseMoneyApplicationMapper.updateById(updateApplication);
        }
        else if(allowVO.getAllowDetailStatus() == USE_MONEY_APPLICATION_STATUS_DENY){
            is_done = true;
            SmsUseMoneyApplication updateApplication = new SmsUseMoneyApplication();
            updateApplication.setId(allowVO.getApplicationId());
            updateApplication.setSmsProcessEndTime(nowDate);
            updateApplication.setSmsApplicationState(USE_MONEY_REGISTER_PROCESS_LOSS);
            smsUseMoneyApplicationMapper.updateById(updateApplication);
        }
        //节点驳回 重置其余节点状态
        if (allowVO.getAllowDetailStatus() == USE_MONEY_APPLICATION_STATUS_DENY) {
            SmsUseMoneyApplicationDetail updateApplicationDetail =
                    new SmsUseMoneyApplicationDetail();
            updateApplicationDetail.setDetailAllowStatus(USE_MONEY_APPLICATION_STATUS_DENY_FINISH);
            smsUseMoneyApplicationDetailMapper.update(updateApplicationDetail, new QueryWrapper<SmsUseMoneyApplicationDetail>()
                    .lambda()
                    .eq(SmsUseMoneyApplicationDetail::getApplicationId, allowVO.getApplicationId())
                    .eq(SmsUseMoneyApplicationDetail::getDetailAllowStatus, USE_MONEY_APPLICATION_STATUS_WAIT_ALLOW));
        }
        //消息通知
        if (is_done) {
            boolean result_status = false;
            if (allowVO.getAllowDetailStatus() == USE_MONEY_APPLICATION_STATUS_PASS) {
                result_status = true;
            }
            newTipsUtil.allowFinishTips(allowVO.getApplicationId(), user_id, result_status);
        } else {
            SmsUseMoneyApplicationDetail nextDetail =
                    smsUseMoneyApplicationDetailMapper.selectOne(new QueryWrapper<SmsUseMoneyApplicationDetail>()
                            .lambda()
                            .eq(SmsUseMoneyApplicationDetail::getApplicationId, allowVO.getApplicationId())
                            .eq(SmsUseMoneyApplicationDetail::getSort, useMoneyApplicationDetail.getSort() + 1));
            RangeTypeEnum rangeTypeEnum;
            if(nextDetail.getProcessIsApplicationEdit().equals(1)){
                rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_PERSON;
            }
            else{
                if (nextDetail.getCheckType() == USE_MONEY_APPLICATION_OBJECT_TYPE_ROLE) {
                    rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_ROLE;
                }else{
                    rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_PERSON;
                }
            }

            List<String> rangeIDList = new ArrayList<>();
            rangeIDList.add(nextDetail.getCheckId());
            newTipsUtil.allowContinueTips(allowVO.getApplicationId(),
                    user_id,
                    rangeTypeEnum,
                    rangeIDList,
                    nextDetail.getId());
        }
        return CommonResult.success();
    }

    @Override
    public ResponseResult getUseMoneyApplicationList(String search_str,String user_id, Integer application_type, Integer pageNum, Integer pageSize) {
        if (isNullOrEmpty(application_type)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        List<SmsUseMoneyApplicationDTO> respList = new ArrayList<>();
        int total = 0;
        if (application_type == USE_MONEY_APPLICATION_TYPE_APPLY) {
            Page<SmsUseMoneyApplication> page = new Page<>(pageNum, pageSize);
            QueryWrapper<SmsUseMoneyApplication> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(SmsUseMoneyApplication::getUserId, user_id)
                    .orderByDesc(SmsUseMoneyApplication::getCreateTime);
            if(!isNullOrEmpty(search_str)){
                queryWrapper.lambda().and(q ->{
                    q.like(SmsUseMoneyApplication::getSmsUseMoneyDepartment,search_str)
                    .or()
                    .like(SmsUseMoneyApplication::getSmsUseMoneyContractNumber,search_str)
                    .or()
                    .like(SmsUseMoneyApplication::getSmsUseMoneyAmountBig,search_str);;
                });
            }
            smsUseMoneyApplicationMapper.selectPage(page, queryWrapper);
            respList = page.getRecords()
                    .stream()
                    .map(smsUseMoneyApplication -> {
                        SmsUseMoneyApplicationDTO smsUseMoneyApplicationDTO =
                                new SmsUseMoneyApplicationDTO();
                        BeanUtils.copyProperties(smsUseMoneyApplication, smsUseMoneyApplicationDTO);
                        smsUseMoneyApplicationDTO.setApplicationId(smsUseMoneyApplication.getId());

                        SmsUser smsUser = cacheUtil.getUserInfo(smsUseMoneyApplication.getUserId());
                        SmsUseMoneyUserDTO smsUseMoneyUserDTO = new SmsUseMoneyUserDTO();
                        if (smsUser != null) {
                            BeanUtils.copyProperties(smsUser, smsUseMoneyUserDTO);
                        }
                        smsUseMoneyApplicationDTO.setApplyUserInfo(smsUseMoneyUserDTO);

                        return smsUseMoneyApplicationDTO;
                    })
                    .collect(Collectors.toList());
            total = (int) page.getTotal();
        }
        else if (application_type == USE_MONEY_APPLICATION_TYPE_ALLOWED) {
            Page<SmsUseMoneyApplicationMpjDTO> page = new Page<>(pageNum, pageSize);
            MPJLambdaWrapper<SmsUseMoneyApplicationDetail> mpjLambdaWrapper = new MPJLambdaWrapper<>();
            mpjLambdaWrapper.selectAll(SmsUseMoneyApplicationDetail.class)
                    .selectAll(SmsUseMoneyApplication.class)
                    .selectAs(SmsUseMoneyApplication::getCreateTime, "createTime")
                    .selectAs(SmsUseMoneyApplicationDetail::getId, "detailId")
                    .leftJoin(SmsUseMoneyApplication.class, SmsUseMoneyApplication::getId, SmsUseMoneyApplicationDetail::getApplicationId)
                    .eq(SmsUseMoneyApplicationDetail::getAllowUserId, user_id)
                    //.orderByDesc(SmsUseMoneyApplication::getCreateTime)
                    .orderByDesc(SmsUseMoneyApplicationDetail::getProcessTime)
            ;
            mpjLambdaWrapper.and(wrapper -> {
                wrapper.eq(SmsUseMoneyApplicationDetail::getDetailAllowStatus, USE_MONEY_APPLICATION_STATUS_PASS)
                        .or()
                        .eq(SmsUseMoneyApplicationDetail::getDetailAllowStatus, USE_MONEY_APPLICATION_STATUS_DENY);
            });
            if(!isNullOrEmpty(search_str)){
                List<String> userIds = smsUserMapper.selectList(new QueryWrapper<SmsUser>()
                        .lambda()
                        .like(SmsUser::getRealName, search_str))
                        .stream()
                        .map(SmsUser::getId).collect(Collectors.toList());

                mpjLambdaWrapper.and(queryWrapper ->{
                    queryWrapper.like(SmsUseMoneyApplication::getSmsUseMoneyContractNumber,search_str)
                            .or()
                            .like(SmsUseMoneyApplication::getSmsUseMoneyDepartment,search_str)
                            .or()
                            .like(SmsUseMoneyApplication::getSmsUseMoneyAmountBig,search_str);
                    if(userIds.size() > 0) {
                        queryWrapper.or().in(SmsAgreementApplication::getApplicationApplyUserId, userIds);
                    }
                });
            }
            smsUseMoneyApplicationMpjMapper.selectJoinPage(page, SmsUseMoneyApplicationMpjDTO.class, mpjLambdaWrapper);

            respList = page.getRecords()
                    .stream()
                    .map(smsApplicationMPJDTO -> {
                        SmsUseMoneyApplicationDTO smsApplicationDTO = new SmsUseMoneyApplicationDTO();
                        BeanUtils.copyProperties(smsApplicationMPJDTO, smsApplicationDTO);
                        smsApplicationDTO.setCreateTime(smsApplicationMPJDTO.getCreateTime());


                        SmsUser applyUser = cacheUtil.getUserInfo(smsApplicationDTO.getUserId());
                        SmsUseMoneyUserDTO smsUseMoneyUserDTO = new SmsUseMoneyUserDTO();
                        if (applyUser != null) {
                            BeanUtils.copyProperties(applyUser, smsUseMoneyUserDTO);
                        }
                        smsApplicationDTO.setApplyUserInfo(smsUseMoneyUserDTO);

                        SmsUser allowUser = cacheUtil.getUserInfo(smsApplicationDTO.getAllowUserId());
                        SmsUseMoneyUserDTO smsUseMoneyAllowUserDTO = new SmsUseMoneyUserDTO();
                        if (allowUser != null) {
                            BeanUtils.copyProperties(allowUser, smsUseMoneyAllowUserDTO);
                        }
                        smsApplicationDTO.setAllowUserInfo(smsUseMoneyAllowUserDTO);

                        return smsApplicationDTO;
                    })
                    .collect(Collectors.toList());
            total = (int) page.getTotal();
        }
        //审批类型为待办
        else if (application_type == USE_MONEY_APPLICATION_TYPE_ALLOW_WAIT_ME) {
            List<String> roleList = cacheUtil.getRoleList(user_id);

            //获取所有待审批申请流程节点
            List<SmsUseMoneyApplicationDetail> detailList
                    = smsUseMoneyApplicationDetailMapper.selectList(new QueryWrapper<SmsUseMoneyApplicationDetail>()
                    .lambda()
                    .eq(SmsUseMoneyApplicationDetail::getDetailAllowStatus, USE_MONEY_APPLICATION_STATUS_WAIT_ALLOW));

            List<SmsUseMoneyApplicationDetail> filterDetailList = detailList.stream()
                    .filter(detail -> {
                        if(detail.getProcessIsApplicationEdit().equals(1)){
                            if (!detail.getCheckId().equals(user_id)) {
                                return false;
                            }
                        }
                        else{
                            if (detail.getCheckType() == PROCESS_PEOPLE_CHECK_TYPE) {
                                if (!detail.getCheckId().equals(user_id)) {
                                    return false;
                                }
                            } else {
                                List<String> filterRoleList = roleList.stream().filter(role -> role.equals(detail.getCheckId())).collect(Collectors.toList());
                                if (filterRoleList.size() < 1) {
                                    return false;
                                }
                            }

                        }

                        if (detail.getSort().equals(1)) {
                            return true;
                        }
                        //判断上一个流程节点是否完成
                        SmsUseMoneyApplicationDetail preDetail =
                                smsUseMoneyApplicationDetailMapper.selectOne(new QueryWrapper<SmsUseMoneyApplicationDetail>()
                                        .lambda()
                                        .eq(SmsUseMoneyApplicationDetail::getApplicationId, detail.getApplicationId())
                                        .eq(SmsUseMoneyApplicationDetail::getSort, detail.getSort() - 1)
                                        .eq(SmsUseMoneyApplicationDetail::getDetailAllowStatus, USE_MONEY_APPLICATION_STATUS_PASS));
                        if (preDetail == null || isNullOrEmpty(preDetail.getId())) {
                            return false;
                        }
                        return true;
                    })
                    .collect(Collectors.toList());
            if (filterDetailList.size() > 0) {
                List<String> detailIDList = filterDetailList.stream().map(SmsUseMoneyApplicationDetail::getId).collect(Collectors.toList());

                Page<SmsUseMoneyApplicationDetail> page = new Page<>(pageNum, pageSize);
                QueryWrapper<SmsUseMoneyApplicationDetail> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda()
                        .in(SmsUseMoneyApplicationDetail::getId, detailIDList)
                        .orderByDesc(SmsUseMoneyApplicationDetail::getCreateTime);
                smsUseMoneyApplicationDetailMapper.selectPage(page, queryWrapper);

                respList = page.getRecords()
                        .stream()
                        .map(smsApplicationDetail -> {
                            SmsUseMoneyApplication smsUseMoneyApplication
                                    = smsUseMoneyApplicationMapper.selectById(smsApplicationDetail.getApplicationId());
                            SmsUseMoneyApplicationDTO smsUseMoneyApplicationDTO
                                    = new SmsUseMoneyApplicationDTO();
                            BeanUtils.copyProperties(smsUseMoneyApplication, smsUseMoneyApplicationDTO);
                            smsUseMoneyApplicationDTO.setApplicationId(smsUseMoneyApplication.getId());
                            SmsUser applyUser = cacheUtil.getUserInfo(smsUseMoneyApplicationDTO.getUserId());
                            SmsUseMoneyUserDTO smsUseMoneyUserDTO = new SmsUseMoneyUserDTO();
                            if (applyUser != null) {
                                BeanUtils.copyProperties(applyUser, smsUseMoneyUserDTO);
                            }
                            smsUseMoneyApplicationDTO.setApplyUserInfo(smsUseMoneyUserDTO);

                            smsUseMoneyApplicationDTO.setDetailId(smsApplicationDetail.getId());

                            return smsUseMoneyApplicationDTO;
                        })
                        .filter(q -> {
                            if(!isNullOrEmpty(search_str)){
                                List<String> userIds = smsUserMapper.selectList(new QueryWrapper<SmsUser>()
                                        .lambda()
                                        .like(SmsUser::getRealName, search_str))
                                        .stream()
                                        .map(SmsUser::getId).collect(Collectors.toList());
                                if(q.getSmsUseMoneyAmountBig().contains(search_str)||q.getSmsUseMoneyContractNumber().contains(search_str)||
                                q.getSmsUseMoneyDepartment().contains(search_str)){
                                        return true;
                                }
                                if(userIds.contains(q.getUserId())){
                                    return true;
                                }
                                return false;
//                                QueryWrapper<SmsUseMoneyApplication> queryWrapper1 = new QueryWrapper<>();
//                                queryWrapper1.lambda().eq(SmsUseMoneyApplication::getId,q.getApplicationId());
//                                queryWrapper1.lambda().and(w ->{
//                                    w.like(SmsUseMoneyApplication::getSmsUseMoneyAmountBig,search_str)
//                                            .or()
//                                            .like(SmsUseMoneyApplication::getSmsUseMoneyContractNumber,search_str)
//                                            .or()
//                                            .like(SmsUseMoneyApplication::getSmsUseMoneyDepartment,search_str);
//                                    if(userIds.size() > 0) {
//                                        w.or().in(SmsUseMoneyApplication::getUserId, userIds);
//                                    }

                            }

                            return true;
                        })
                        .collect(Collectors.toList());

            }
        }
        return CommonResult.success(respList,respList.size());

//
        }


    @Override
    public ResponseResult getUseMoneyApplicationDetail(String application_id, String user_id) {
        if(isNullOrEmpty(application_id)){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsUseMoneyApplication smsUseMoneyApplication = smsUseMoneyApplicationMapper.selectById(application_id);
        if(smsUseMoneyApplication==null||isNullOrEmpty(smsUseMoneyApplication.getId())){
            return CommonResult.failed(CommonCodeEnum.USE_MONEY_NOT_EXIST);
        }
        SmsUseMoneyApplicationDTO smsUseMoneyApplicationDTO = new SmsUseMoneyApplicationDTO();
        BeanUtils.copyProperties(smsUseMoneyApplication,smsUseMoneyApplicationDTO);
        smsUseMoneyApplicationDTO.setApplicationId(smsUseMoneyApplication.getId());
        SmsUser smsUser = cacheUtil.getUserInfo(smsUseMoneyApplicationDTO.getUserId());
        SmsUseMoneyUserDTO smsUseMoneyUserDTO = new SmsUseMoneyUserDTO();
        if (smsUser != null) {
            BeanUtils.copyProperties(smsUser, smsUseMoneyUserDTO);

        }
        smsUseMoneyApplicationDTO.setApplyUserInfo(smsUseMoneyUserDTO);

        List<SmsUseMoneyApplicationDetailDTO> detailRespList =
                smsUseMoneyApplicationDetailMapper.selectList(new QueryWrapper<SmsUseMoneyApplicationDetail>()
                        .lambda()
                        .eq(SmsUseMoneyApplicationDetail::getApplicationId, application_id)
                        .orderByAsc(SmsUseMoneyApplicationDetail::getSort))
                        .stream()
                        .map(detail -> {
                            SmsUseMoneyApplicationDetailDTO detailResp = new SmsUseMoneyApplicationDetailDTO();
                            BeanUtils.copyProperties(detail, detailResp);
                            detailResp.setProcessIsSign(detail.getProcessIsSign());
                            detailResp.setProcessIsStamp(detail.getProcessIsStamp());
                            if(detailResp.getCheckType()==USE_MONEY_APPLICATION_OBJECT_TYPE_PERSON){
                                SmsUser smsUser1 = smsUserMapper.selectById(detailResp.getCheckId());
                                detailResp.setRealName(smsUser1.getRealName());
                                detailResp.setHeadPic(smsUser1.getUserPic());
                            }
                            else if(detailResp.getCheckType()==USE_MONEY_APPLICATION_OBJECT_TYPE_ROLE){
                                SmsRole smsRole = smsRoleMapper.selectById(detailResp.getCheckId());
                                detailResp.setRealName(smsRole.getRoleName());
                            }

                            if (!isNullOrEmpty(detailResp.getAllowUserId())) {
                                SmsUser userInfo = cacheUtil.getUserInfo(detailResp.getAllowUserId());
                                SmsUseMoneyUserDTO smsUseMoneyUserDTO1 = new SmsUseMoneyUserDTO();
                                if (userInfo != null) {
                                    BeanUtils.copyProperties(userInfo, smsUseMoneyUserDTO1);
                                }
                                detailResp.setAllowUserInfo(smsUseMoneyUserDTO1);
                            }
                            return detailResp;
                        })
                        .collect(Collectors.toList());
        smsUseMoneyApplicationDTO.setDetailList(detailRespList);
        return CommonResult.success(smsUseMoneyApplicationDTO);
    }

    @Override
    public ResponseResult getUseMoneyApplicationOriginSettingProcess() {
        List<SmsUseMoneyOriginSettingProcessDTO> respList =
                smsUseMoneyApplicationProcessMapper.selectList(new QueryWrapper<SmsUseMoneyApplicationProcess>()
                        .lambda()
                        .eq(SmsUseMoneyApplicationProcess::getProcessIsApplicationEdit, true)
                        .eq(SmsUseMoneyApplicationProcess::getIsUse,true)
                        .orderByAsc(SmsUseMoneyApplicationProcess::getSort))
                        .stream()
                        .map(process -> {
                            SmsUseMoneyOriginSettingProcessDTO smsUseMoneyOriginSettingProcessDTO =
                                    new SmsUseMoneyOriginSettingProcessDTO();
                            BeanUtils.copyProperties(process, smsUseMoneyOriginSettingProcessDTO);
                            return smsUseMoneyOriginSettingProcessDTO;
                        })
                        .collect(Collectors.toList());
        return CommonResult.success(respList);
    }

    @Autowired
    XWPFTUtil xwpftUtil;
    @Override
    @Async
    public Future<ResponseResult> tableDownload(String apply_id, HttpServletResponse response) {
        SmsUseMoneyApplication useMoneyApplication = smsUseMoneyApplicationMapper.selectById(apply_id);
        if (useMoneyApplication == null || useMoneyApplication.getId() == null) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.USE_MONEY_NOT_EXIST));
        }
//        if (useMoneyApplication.getSmsApplicationState() == USE_MONEY_REGISTER_PROCESS_WAITING) {
//            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.WORK_APPLICATION_DOWNLOAD_FAIL));
//        }

        String OSName = System.getProperty("os.name");
        String filePath = OSName.toLowerCase().startsWith("win") ? fileSavePathConstant.getFILE_DOWNLOAD_PATH()
                : fileSavePathConstant.getFILE_DOWNLOAD_PATH_LINUX();

        String newFilePath = filePath + apply_id + ".docx";
        String pdfFilePath = filePath + apply_id + ".pdf";

        File pdfFile = new File(pdfFilePath);

      //  if (!pdfFile.exists()) {
            try {

                String signTime = TimeUtil.DateHanZiSimpleFormat(useMoneyApplication.getCreateTime());

                List<String> picTagList = new ArrayList<>();

                Map<String, Object> map = new HashMap<>();
                map.put("createTime", signTime);
                map.put("reason", useMoneyApplication.getSmsUseMoneyReason());
                map.put("way", useMoneyApplication.getSmsUseMoneyWay());
                map.put("ticket",useMoneyApplication.getSmsUseMoneyOpenTicket());
                map.put("big", useMoneyApplication.getSmsUseMoneyAmountSmall());
                map.put("small", useMoneyApplication.getSmsUseMoneyAmountBig());
                map.put("department", useMoneyApplication.getSmsUseMoneyDepartment());
                map.put("contractNumber", useMoneyApplication.getSmsUseMoneyContractNumber());
                map.put("applyPerson", useMoneyApplication.getSmsUseMoneyApplicationPerson());
                map.put("descriptionPay", useMoneyApplication.getSmsUseMoneyDescriptionPay());
                map.put("getMoneyUnitName", useMoneyApplication.getSmsUseMoneyGetMoneyUnitName());
                map.put("bankNum", useMoneyApplication.getSmsUseMoneyBankNumber());
                map.put("bankOfOpen", useMoneyApplication.getSmsUseMoneyBankOfOpen());
                if(isNullOrEmpty(useMoneyApplication.getSmsUseMoneySettlementAmount())){
                    map.put("amount", "");
                }else{
                    map.put("amount", useMoneyApplication.getSmsUseMoneySettlementAmount()+"元");
                }



                //获取初始流程
                List<SmsUseMoneyApplicationProcess> processList = smsUseMoneyApplicationProcessMapper.selectList(new QueryWrapper<SmsUseMoneyApplicationProcess>()
                        .lambda()
                        .orderByAsc(SmsUseMoneyApplicationProcess::getSort));
                if (processList == null || processList.size() < 1) {
                    return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
                }

                //获取申请流程
                List<SmsUseMoneyApplicationDetail> detailList = smsUseMoneyApplicationDetailMapper.selectList(new QueryWrapper<SmsUseMoneyApplicationDetail>()
                        .lambda()
                        .eq(SmsUseMoneyApplicationDetail::getApplicationId, apply_id));
                for (SmsUseMoneyApplicationProcess process : processList) {
                    List<SmsUseMoneyApplicationDetail> filterDetail = detailList
                            .stream()
                            .filter(detail -> detail.getProcessId().equals(process.getId()))
                            .collect(Collectors.toList());
                    if (filterDetail.size() > 0) {
                        SmsUseMoneyApplicationDetail detail = filterDetail.get(0);
                        if (detail.getDetailAllowStatus() == EXAMINE_STATUS_PASS) {
                            map.put("allowStatus" + process.getSort() + "", "同意");
                        } else if (detail.getDetailAllowStatus() == EXAMINE_STATUS_DENY) {
                            map.put("allowStatus" + process.getSort() + "", "拒绝");
                        } else {
                            map.put("allowStatus" + process.getSort() + "", "");
                        }

                        map.put("allowOption" + process.getSort() + "", detail.getDetailAllowOption());

                        //添加签名
                        if (isNullOrEmpty(detail.getDetailAllowSign())) {
                            map.put("allowSign" + process.getSort() + "", "");
                        } else {
                            String[] splitStr = detail.getDetailAllowSign().split("=");
                            String fileName = splitStr[splitStr.length - 1];

                            File file = new File(filePath + fileName);
                            if (file.exists()) {
                                InputStream inputStream = new FileInputStream(file);
                                PictureRenderData pictures = Pictures.ofStream(inputStream,
                                        PictureType.PNG).size(60, 30).create();

                                map.put("allowSign" + process.getSort() + "", pictures);
                                picTagList.add("allowSign" + process.getSort());
                            }

                        }

                        //添加印章
                        if (isNullOrEmpty(detail.getDetailAllowStamp())) {
                            map.put("allowStamp" + process.getSort() + "", "");
                        } else {
                            String[] splitStr = detail.getDetailAllowStamp().split("=");
                            String fileName = splitStr[splitStr.length - 1];

                            File file = new File(filePath + fileName);
                            if (file.exists()) {
                                InputStream inputStream = new FileInputStream(file);
                                PictureRenderData pictures = Pictures.ofStream(inputStream,
                                        PictureType.PNG).size(60, 60).create();

                                map.put("allowStamp" + process.getSort() + "", pictures);
                                picTagList.add("allowStamp" + process.getSort());
                            }

                        }

                        //审批时间
                        if (isNullOrEmpty(detail.getProcessTime())) {
                            map.put("processTime" + process.getSort() + "", "");
                        } else {
                            map.put("processTime" + process.getSort() + "", TimeUtil.DateHanZiSimpleFormat(detail.getProcessTime()));
                        }
                    } else {
                        map.put("allowStatus" + process.getSort() + "", "");
                        map.put("allowOption" + process.getSort() + "", "");
                        map.put("allowSign" + process.getSort() + "", "");
                        map.put("allowStamp" + process.getSort() + "", "");
                        map.put("processTime" + process.getSort() + "", "");
                    }
                }


                ClassPathResource resource = new ClassPathResource("applyTemplates/useMoneyApplication.docx");
                InputStream is = resource.getInputStream();
                FileOutputStream outputStream = new FileOutputStream(newFilePath);

                XWPFTemplate template = XWPFTemplate.compile(is);

                //配置图片标签
                Configure config = template.getConfig();
                for (String tag : picTagList
                ) {
                    config.customPolicy(tag, new PictureRenderPolicy());
                }
                template.render(map);

                template.write(outputStream);

                is.close();
                outputStream.close();
                template.close();

                //word转pdf
                File destOri = new File(newFilePath);
                FileInputStream fileInputStream = new FileInputStream(destOri);
                FileOutputStream fileOutputStream = new FileOutputStream(pdfFilePath);

                Document document = new Document();
                document.loadFromStream(fileInputStream, FileFormat.Docx);
                //保存为PDF
                document.saveToFile(pdfFilePath, FileFormat.PDF);


                fileInputStream.close();
                fileOutputStream.close();
                document.close();

                log.debug("文件生成完成!");
            } catch (Exception e) {
                e.printStackTrace();
                return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
            }
    //    }
        try {
            // 加载PDF文档
            PDDocument doc = PDDocument.load(pdfFile);
            doc.setAllSecurityToBeRemoved(true);
            // 创建水印
//            String watermark = "南充电影工业职业学院";
//            PDPageContentStream contentStream;
//
//            for (PDPage page : doc.getPages()) {
//                contentStream = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true);
//
//                //加载字体
//                ClassPathResource resource = new ClassPathResource("fonts/123.ttf");
//                InputStream is = resource.getInputStream();
//                PDFont font = PDType0Font.load(doc, is);
//
//
//                int startX = 0; // 起始位置 x 坐标
//                int startY = 0; // 起始位置 y 坐标
//                float angle = -45; // 角度
//                float interval = 220; // 间隔
//                float opacity = 0.3f; // 透明度
//                int colorR = 127; // 颜色 red 值
//                int colorG = 127; // 颜色 green 值
//                int colorB = 127; // 颜色 blue 值
//
//                //透明的
//                PDExtendedGraphicsState r0 = new PDExtendedGraphicsState();
//                r0.setNonStrokingAlphaConstant(opacity);
//                r0.setAlphaSourceFlag(true);
//                contentStream.setGraphicsStateParameters(r0);
//
//                //水印颜色
//                contentStream.setNonStrokingColor(colorR, colorG, colorB);
//                contentStream.beginText();
//                contentStream.setFont(font, 30f);
//
//                int x_times = (int) Math.ceil(page.getMediaBox().getWidth() / interval);
//                int y_times = (int) Math.ceil(page.getMediaBox().getHeight() / interval);
//                for (int x = startX; x <= x_times; x++) {
//                    for (int y = startY; y <= y_times; y++) {
//                        contentStream.setTextRotation(angle, (x * interval), (y * interval));
//                        contentStream.showText(watermark);
//                    }
//                }
//                contentStream.endText();
//                contentStream.restoreGraphicsState();
//                contentStream.close();
//                is.close();
//            }

//            response.reset();
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/vnd.pdf;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("用款申请单预览.pdf", "utf-8"));
            response.setHeader("file-name", URLEncoder.encode("用款申请单预览.pdf", "utf-8"));
            response.setHeader("file-type","download");
            response.setHeader("Access-Control-Expose-Headers", "file-type,file-name");
            //刷新缓冲
            response.flushBuffer();

            // 保存PDF文档
            doc.save(response.getOutputStream());
            doc.close();
        } catch (Exception e) {
            e.printStackTrace();
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));

        }
        return null;


        //        SmsUseMoneyApplication smsUseMoneyApplication = smsUseMoneyApplicationMapper.selectById(apply_id);
//        if (smsUseMoneyApplication == null || smsUseMoneyApplication.getId() == null) {
//            return CommonResult.failed(CommonCodeEnum.USE_MONEY_NOT_EXIST);
//        }
//        if (smsUseMoneyApplication.getSmsApplicationState() == USE_MONEY_APPLICATION_STATUS_WAIT_ALLOW) {
//            return CommonResult.failed(CommonCodeEnum.WORK_APPLICATION_DOWNLOAD_FAIL);
//        }
//
//        String OSName = System.getProperty("os.name");
//        String filePath = OSName.toLowerCase().startsWith("win") ? FILE_DOWNLOAD_PATH
//                : FILE_DOWNLOAD_PATH_LINUX;
//
//        String newFilePath = filePath + apply_id + ".docx";
//        String pdfFilePath = filePath + apply_id + ".pdf";
//
//        File pdfFile = new File(pdfFilePath);
//        if (!pdfFile.exists()) {
//            try {
////                String isAnnex = "";
////                if (smsUseMoneyApplication.getIsAnnex() == HAVE_ANNEX) {
////                    isAnnex = "是";
////                } else {
////                    isAnnex = "否";
////                }
//                Map<String, Object> map = new HashMap<>();
//                map.put("${createTime}", TimeUtil.DateHanZiSimpleFormat(smsUseMoneyApplication.getCreateTime()));
//                map.put("${moneyReason}", smsUseMoneyApplication.getSmsUseMoneyReason());
//                map.put("${moneyWay}", smsUseMoneyApplication.getSmsUseMoneyWay());
//                map.put("${moneyOpenTicket}", smsUseMoneyApplication.getSmsUseMoneyOpenTicket());
//                map.put("${moneyAmountBig}", smsUseMoneyApplication.getSmsUseMoneyAmountBig());
//                map.put("${moneyDepartment}", smsUseMoneyApplication.getSmsUseMoneyDepartment());
//                map.put("${contractNumber}", smsUseMoneyApplication.getSmsUseMoneyContractNumber());
//                map.put("${applicationPerson}", smsUseMoneyApplication.getSmsUseMoneyApplicationPerson());
//                map.put("${descriptionPay}", smsUseMoneyApplication.getSmsUseMoneyDescriptionPay());
//                map.put("${getMoneyUnitName}", smsUseMoneyApplication.getSmsUseMoneyGetMoneyUnitName());
//                map.put("${bankNum}", smsUseMoneyApplication.getSmsUseMoneyBankNumber());
//                map.put("${bankOfOpen}", smsUseMoneyApplication.getSmsUseMoneyBankOfOpen());
//                map.put("${amount}", smsUseMoneyApplication.getSmsUseMoneySettlementAmount());
//
//                //获取初始流程
//                List<SmsUseMoneyApplicationProcess> processList = smsUseMoneyApplicationProcessMapper.selectList(new QueryWrapper<SmsUseMoneyApplicationProcess>()
//                        .lambda()
//                        .orderByAsc(SmsUseMoneyApplicationProcess::getSort));
//                if (processList == null || processList.size() < 1) {
//                    return CommonResult.failed(CommonCodeEnum.FAIL);
//                }
//
//                //获取申请流程
//                List<SmsUseMoneyApplicationDetail> detailList = smsUseMoneyApplicationDetailMapper.selectList(new QueryWrapper<SmsUseMoneyApplicationDetail>()
//                        .lambda()
//                        .eq(SmsUseMoneyApplicationDetail::getApplicationId, apply_id));
//                for (SmsUseMoneyApplicationProcess process : processList) {
//                    List<SmsUseMoneyApplicationDetail> filterDetail = detailList
//                            .stream()
//                            .filter(detail -> detail.getProcessId().equals(process.getId()))
//                            .collect(Collectors.toList());
//                    if (filterDetail.size() > 0) {
//                        SmsUseMoneyApplicationDetail detail = filterDetail.get(0);
//                        if (detail.getDetailAllowStatus() == USE_MONEY_APPLICATION_STATUS_PASS) {
//                            map.put("${allowStatus" + process.getSort() + "}", "同意");
//                        } else if (detail.getDetailAllowStatus() == USE_MONEY_APPLICATION_STATUS_DENY) {
//                            map.put("${allowStatus" + process.getSort() + "}", "拒绝");
//                        } else {
//                            map.put("${allowStatus" + process.getSort() + "}", "");
//                        }
//
//                        map.put("${allowOption" + process.getSort() + "}", detail.getDetailAllowOption());
//
//
//                        //添加签名
//                        if (isNullOrEmpty(detail.getDetailAllowSign())) {
//                            map.put("${allowSign" + process.getSort() + "}", "");
//                        } else {
//                            String[] splitStr = detail.getDetailAllowSign().split("=");
//                            String fileName = splitStr[splitStr.length - 1];
//
//                            Map<String, Object> signMap = new HashMap<>();
//                            signMap.put("name", fileName);
//
//                            File file = new File(filePath + fileName);
//                            InputStream inputStream = new FileInputStream(file);
//                            signMap.put("picInputStream", inputStream);
//
//                            String[] typeSplit = fileName.split("u002E");
//                            String type = typeSplit[typeSplit.length - 1];
//                            signMap.put("type", type);
//
//                            map.put("${allowSign" + process.getSort() + "}", signMap);
//                        }
//
//                        //添加印章
//                        if (isNullOrEmpty(detail.getDetailAllowStamp())) {
//                            map.put("${allowStamp" + process.getSort() + "}", "");
//                        } else {
//                            String[] splitStr = detail.getDetailAllowStamp().split("=");
//                            String fileName = splitStr[splitStr.length - 1];
//
//                            Map<String, Object> stampMap = new HashMap<>();
//                            stampMap.put("name", fileName);
//
//                            File file = new File(filePath + fileName);
//                            InputStream inputStream = new FileInputStream(file);
//                            stampMap.put("picInputStream", inputStream);
//
//                            String[] typeSplit = fileName.split("u002E");
//                            String type = typeSplit[typeSplit.length - 1];
//                            stampMap.put("type", type);
//
//                            map.put("${allowStamp" + process.getSort() + "}", stampMap);
//                        }
//                    } else {
//                        map.put("${allowStatus" + process.getSort() + "}", "");
//                        map.put("${allowOption" + process.getSort() + "}", "");
//                        map.put("${allowSign" + process.getSort() + "}", "");
//                        map.put("${allowStamp" + process.getSort() + "}", "");
//                    }
//                }
//
//                InputStream is = null;
//
//                ClassPathResource resource = new ClassPathResource("applyTemplates/useMoneyApplication.docx");
//                is = resource.getInputStream();
//                XWPFDocument doc = new XWPFDocument(is);
//
//                xwpftUtil.replaceInPara(doc, map);
//                xwpftUtil.replaceInTable(doc, map);
//
//
//                FileOutputStream outputStream = new FileOutputStream(newFilePath);
//
//                doc.write(outputStream);
//                is.close();
//
//                outputStream.close();
//                doc.close();
//
//                File destOri = new File(newFilePath);
//
//                FileInputStream fileInputStream = new FileInputStream(destOri);
//                XWPFDocument xwpfDocument = new XWPFDocument(fileInputStream);
//                PdfOptions pdfOptions = PdfOptions.create();
//                FileOutputStream fileOutputStream = new FileOutputStream(pdfFilePath);
//                PdfConverter.getInstance().convert(xwpfDocument, fileOutputStream, pdfOptions);
//
//
//                fileInputStream.close();
//                xwpfDocument.close();
//                fileOutputStream.close();
//
//                log.debug("文件生成完成!");
//            } catch (Exception e) {
//                e.printStackTrace();
//                return CommonResult.failed(CommonCodeEnum.FAIL);
//            }
//        }
//        try {
//            // 加载PDF文档
//            PDDocument doc = PDDocument.load(pdfFile);
//            doc.setAllSecurityToBeRemoved(true);
//            // 创建水印
//            String watermark = "南充电影学院";
//            PDPageContentStream contentStream;
//
//            for (PDPage page : doc.getPages()) {
//                contentStream = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true);
//
//                //加载字体
//                ClassPathResource resource = new ClassPathResource("fonts/123.ttf");
//                InputStream is = resource.getInputStream();
//                PDFont font = PDType0Font.load(doc, is);
//
//
//                int startX = 0; // 起始位置 x 坐标
//                int startY = 0; // 起始位置 y 坐标
//                float angle = -45; // 角度
//                float interval = 160; // 间隔
//                float opacity = 0.3f; // 透明度
//                int colorR = 127; // 颜色 red 值
//                int colorG = 127; // 颜色 green 值
//                int colorB = 127; // 颜色 blue 值
//
//                //透明的
//                PDExtendedGraphicsState r0 = new PDExtendedGraphicsState();
//                r0.setNonStrokingAlphaConstant(opacity);
//                r0.setAlphaSourceFlag(true);
//                contentStream.setGraphicsStateParameters(r0);
//
//                //水印颜色
//                contentStream.setNonStrokingColor(colorR, colorG, colorB);
//                contentStream.beginText();
////                contentStream.setFont(PDType1Font.HELVETICA, 30f);
//                contentStream.setFont(font, 30f);
////                page.getResources().add(font);
//                for (int x = startX; x < page.getMediaBox().getWidth(); x += interval) {
//                    for (int y = startY; y < page.getMediaBox().getHeight(); y += interval) {
//                        contentStream.setTextRotation(angle, x, y);
//                        contentStream.showText(watermark);
//                    }
//                }
//                contentStream.endText();
//                contentStream.restoreGraphicsState();
//                is.close();
//                contentStream.close();
//
//            }
//
////            response.reset();
//            response.setCharacterEncoding("utf-8");
//            response.setContentType("application/vnd.pdf;charset=utf-8");
//            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("用款请示单预览.pdf", "utf-8"));
//
//            //刷新缓冲
//            response.flushBuffer();
//            // 保存PDF文档
//            OutputStream outputStream = response.getOutputStream();
//            doc.save(outputStream);
//            outputStream.close();
//            doc.close();
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//        return null;
    }

    @Override
    public ResponseResult selectAllUseMoneyApply(String apply_unit, Integer pageSize, Integer pageNum) {
        QueryWrapper<SmsUseMoneyApplication> queryWrapper = new QueryWrapper<>();
        if (!isNullOrEmpty(apply_unit)) {
            queryWrapper.lambda().like(SmsUseMoneyApplication::getSmsUseMoneyDepartment, apply_unit);
        }
        queryWrapper.orderByDesc("create_time");
        Page<SmsUseMoneyApplication> page = new Page<>(pageNum, pageSize);
        List<SmsUseMoneyApplicationDTO> collect ;

        Page<SmsUseMoneyApplication> appApplicationPage = smsUseMoneyApplicationMapper.selectPage(page, queryWrapper);
        List<SmsUseMoneyApplication> records = appApplicationPage.getRecords();
        collect = records.stream().map(appApplication -> {
            SmsUseMoneyApplicationDTO appApplicationResp = new SmsUseMoneyApplicationDTO();
            BeanUtils.copyProperties(appApplication, appApplicationResp);
            SmsUser smsUser = cacheUtil.getUserInfo(appApplicationResp.getUserId());
            if (smsUser != null) {
                SmsUseMoneyUserDTO user = new SmsUseMoneyUserDTO();
                BeanUtils.copyProperties(smsUser, user);
                appApplicationResp.setApplyUserInfo(user);
            }

            return appApplicationResp;
        }).collect(Collectors.toList());

        int total = (int) page.getTotal();
        return CommonResult.success(collect, total);
    }

    @Override
    @Async
    public Future<ResponseResult> exportUseMoneyApplication(SmsUseMoneyApplicationExportVO exportVO, HttpServletResponse response) {
        if (isNullOrEmpty(exportVO.getIsExportProcess())) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        try {
            QueryWrapper<SmsUseMoneyApplication> queryWrapper = new QueryWrapper<>();

            if (!isNullOrEmpty(exportVO.getSmsUseMoneyDepartment())) {
                queryWrapper.lambda().like(SmsUseMoneyApplication::getSmsUseMoneyDepartment, exportVO.getSmsUseMoneyDepartment());
            }

            queryWrapper.lambda().orderByDesc(SmsUseMoneyApplication::getCreateTime);
            List<SmsUseMoneyApplication> list = smsUseMoneyApplicationMapper.selectList(queryWrapper);
            //表头数据
            String[] header = exportVO.getLimitColumn().toArray(new String[0]);
            double sheetNum;
            //声明一个工作簿
            HSSFWorkbook workbook = new HSSFWorkbook();
            if (list != null && list.size() > 0) {
                sheetNum = Math.ceil((double) list.size() / PER_SHEET_NUM);
                for (int k = 0; k < sheetNum; k++) {
                    //生成一个表格，设置表格名称为"资源导出表"
                    HSSFSheet sheet = workbook.createSheet("用款请示单记录导出表" + (k + 1));

                    //设置表格列宽度为10个字节
                    sheet.setDefaultColumnWidth(12);
                    //创建标题的显示样式
                    HSSFCellStyle headerStyle = workbook.createCellStyle();
                    headerStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
                    headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

                    HSSFFont f = workbook.createFont();
                    f.setFontHeightInPoints((short) 10);//字号
                    f.setBold(true);//加粗
                    headerStyle.setFont(f);
                    //创建第一行表头
                    HSSFRow headrow = sheet.createRow(0);

                    //遍历添加表头(下面模拟遍历学生，也是同样的操作过程)
                    for (int i = 0; i < header.length + 1; i++) {
                        //创建一个单元格
                        HSSFCell cell = headrow.createCell(i);

                        if (i == 0) {
                            //创建一个内容对象
                            HSSFRichTextString text = new HSSFRichTextString("序号");
                            //将内容对象的文字内容写入到单元格中
                            cell.setCellValue(text);
                            cell.setCellStyle(headerStyle);
                            continue;
                        }
                        //创建一个内容对象
                        String header1 = apiModelUtil.getFieldValueByFieldName(SmsUseMoneyApplication.class, header[i - 1]);
                        HSSFRichTextString text = new HSSFRichTextString(header1);

                        //将内容对象的文字内容写入到单元格中
                        cell.setCellValue(text);
                        cell.setCellStyle(headerStyle);
                    }

                    //判断是否需要添加流程表头
                    if (exportVO.getIsExportProcess() == EXPORT_PROCESS_TRUE) {
                        List<SmsUseMoneyApplicationProcess> processList =
                                smsUseMoneyApplicationProcessMapper.selectList(new QueryWrapper<>());
                        if (processList != null && processList.size() > 0) {
                            Integer origin_num = header.length + 1;
                            for (SmsUseMoneyApplicationProcess process : processList) {
                                String process_name = process.getProcessName();
                                addProcessTableHead(headrow, headerStyle, origin_num, process_name);
                                origin_num += 4;
                            }
                        }
                    }

                    int range = PER_SHEET_NUM;
                    if (k + 1 == sheetNum) {
                        range = list.size() - (PER_SHEET_NUM) * k;
                    }
                    for (int i = 0; i < range; i++) {
                        //创建一行
                        HSSFRow row1 = sheet.createRow(i + 1);
                        SmsUseMoneyApplication useMoneyApplication = list.get((PER_SHEET_NUM) * k + i);
                        Map map = JSONObject.parseObject(JSON.toJSONString(useMoneyApplication), Map.class);
                        row1.createCell(0).setCellValue(new HSSFRichTextString(i + 1 + ""));
                        for (int j = 0; j < header.length; j++) {
                            String rowContent = "";
                            if (map.get(header[j]) instanceof Long) {
                                rowContent = TimeUtil.DateformatTimestamp((long) map.get(header[j]));
                            } else {
                                if (header[j].equals("userId")) {
                                    SmsUser smsUser = cacheUtil.getUserInfo(useMoneyApplication.getUserId());
                                    if (smsUser != null) {
                                        rowContent = smsUser.getRealName();
                                    } else {
                                        rowContent = "";
                                    }
                                }  else {
                                    rowContent = (String) map.get(header[j]);
                                }
                            }
                            row1.createCell(j + 1).setCellValue(new HSSFRichTextString(rowContent));
                        }

                        if (exportVO.getIsExportProcess() == EXPORT_PROCESS_TRUE) {
                            List<SmsUseMoneyApplicationProcess> processList =
                                    smsUseMoneyApplicationProcessMapper.selectList(new QueryWrapper<>());
                            if (processList != null && processList.size() > 0) {
                                Integer origin_num = header.length + 1;
                                for (SmsUseMoneyApplicationProcess process : processList) {
                                    SmsUseMoneyApplicationDetail detail =
                                            smsUseMoneyApplicationDetailMapper.selectOne(new QueryWrapper<SmsUseMoneyApplicationDetail>()
                                                    .lambda()
                                                    .eq(SmsUseMoneyApplicationDetail::getApplicationId, useMoneyApplication.getId())
                                                    .eq(SmsUseMoneyApplicationDetail::getProcessId, process.getId()));
                                    if (detail == null || detail.getId() == null) {
                                        origin_num += 4;
                                    } else {
                                        //审批人
                                        SmsUser user = cacheUtil.getUserInfo(detail.getAllowUserId());
                                        if (user == null) {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString(""));
                                        } else {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString(user.getRealName()));
                                        }

                                        //审批时间
                                        Date allow_time = detail.getProcessTime();
                                        if (allow_time == null) {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString(""));
                                        } else {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString(TimeUtil.DateHanZiSimpleFormat(allow_time)));
                                        }

                                        //审批状态
                                        Integer allow_status = detail.getDetailAllowStatus();
                                        if (allow_status == EXAMINE_STATUS_PASS) {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString("同意"));
                                        } else if (allow_status == EXAMINE_STATUS_DENY) {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString("拒绝"));
                                        } else {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString(""));
                                        }

                                        //审批意见
                                        String allow_option = detail.getDetailAllowOption();
                                        if (isNullOrEmpty(allow_option)) {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString(""));
                                        } else {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString(allow_option));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

//            response.reset();
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("用款申请记录导出表.xlsx", "utf-8"));
            response.setCharacterEncoding("utf-8");
            response.setHeader("file-type", "download");
            response.setHeader("file-name", URLEncoder.encode("用款申请记录导出表.xlsx", "utf-8"));
            response.setHeader("Access-Control-Expose-Headers", "file-type,file-name");
//            //刷新缓冲
            response.flushBuffer();
            //workbook将Excel写入到response的输出流中，供页面下载
            OutputStream os = response.getOutputStream();
            workbook.write(os);

            workbook.close();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
        }
        return null;
    }
    private void addProcessTableHead(HSSFRow headRow, HSSFCellStyle headerStyle, Integer origin_cell_num, String originHeadContent) {
        Integer cell_num = origin_cell_num;

        setTableHead(headRow, headerStyle, cell_num++, originHeadContent + "审批人");
        setTableHead(headRow, headerStyle, cell_num++, originHeadContent + "审批时间");
        setTableHead(headRow, headerStyle, cell_num++, originHeadContent + "审批状态");
        setTableHead(headRow, headerStyle, cell_num, originHeadContent + "审批意见");

    }
    private void setTableHead(HSSFRow headRow, HSSFCellStyle headerStyle, Integer cell_num, String headContent) {
        HSSFCell cell = headRow.createCell(cell_num);
        //创建一个内容对象
        HSSFRichTextString text = new HSSFRichTextString(headContent);

        //将内容对象的文字内容写入到单元格中
        cell.setCellValue(text);
        cell.setCellStyle(headerStyle);
    }
}
